/*
 * This file is part of aion-emu <aion-emu.com>.
 *
 *  aion-emu is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  aion-emu is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with aion-emu.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.aionemu.gameserver.network.aion.serverpackets;

import java.util.List;

import com.aionemu.gameserver.model.gameobjects.Creature;
import com.aionemu.gameserver.model.gameobjects.Creature.MoveData;
import com.aionemu.gameserver.model.gameobjects.NpcWhichNotGatherable;
import com.aionemu.gameserver.model.gameobjects.interfaces.ISummoned;
import com.aionemu.gameserver.model.gameobjects.player.Player;
import com.aionemu.gameserver.model.gameobjects.stats.Stat;
import com.aionemu.gameserver.model.templates.npcTemplate.NpcTemplate;
import com.aionemu.gameserver.model.templates.spawn.SpawnTemplate;
import com.aionemu.gameserver.network.aion.AbstractAionServerPacket;
import com.aionemu.gameserver.network.aion.GameClient;

/**
 * This packet is displaying visible npc/monsters.
 * 
 * @author Lyahim, -Nemesiss-
 * 
 */
public class SM_NPC_INFO extends AbstractAionServerPacket<GameClient>
{
	private final NpcWhichNotGatherable	npc;
	private final int					npcTypeId;

	/**
	 * Constructs new <tt>SM_NPC_INFO </tt> packet
	 * 
	 * @param npc
	 *            visible npc.
	 * @param player 
	 */
	public SM_NPC_INFO(NpcWhichNotGatherable npc, Player player)
	{
		this.npc = npc;
		npcTypeId = npc.getRelation(player).value();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void writeImpl(GameClient client)
	{
		NpcTemplate template = null;
		if (npc.getObjectTemplate() instanceof NpcTemplate)
			template = (NpcTemplate) npc.getObjectTemplate();
		if (template == null)
			return;
		writeF(npc.getX());// x
		writeF(npc.getY());// y
		writeF(npc.getZ());// z
		writeD(npc.getObjectId());
		//		writeD(npcId);
		//		writeD(npcId);
		writeD(template.getTemplateId());
		writeD(template.getTemplateId());

		writeC(npcTypeId);

		writeH(npc.getState());// unk 65=normal,0x47 (71)= [dead npc ?]no drop,0x21(33)=fight state,0x07=[dead monster?]
								// no drop
								// 3,19 - wings spread (NPCs)
								// 5,6,11,21 - sitting (NPC)
								// 7,23 - dead (no drop)
								// 8,24 - [dead][NPC only] - looks like some orb of light (no normal mesh)
								// 32,33 - fight mode

		writeC(npc.getHeading());
		writeD(template.getNameId());
		writeD(template.getCommonData().getTitleId());// titleID

		writeH(0x00);// unk
		writeC(0x00);// unk
		writeD(0x00);// unk

		/*
		 * Master Info (Summon, Kisk, Etc)
		 */
		if (npc instanceof ISummoned && ((ISummoned) npc).getMaster() != null)
		{
			writeD(((ISummoned) npc).getMaster().getObjectId());// masterObjectId
			writeS(((ISummoned) npc).getMaster().getName());// masterName
		}
		else
		{
			writeD(0);
			writeH(0);
		}

		int maxHp = npc.getGameStats().getMaxHP().getCurrentInt();
		int currHp = maxHp;
		if (npc instanceof Creature)
			((Creature)npc).getLifeStats().getCurrentHp();
		writeC(100 * currHp / maxHp);// %hp
		writeD(currHp);
		writeC(npc.getLevel());// lvl

		//		NpcEquippedGear gear = npcTemplate.getEquipment();
		List<Integer> gear = template.getCommonData().getEquipment();
		if (gear == null)
			writeH(0x00);
		else
		{
			writeH(template.getCommonData().getEquipmentMask());
			for (int itemId : gear) // getting it from template ( later if we make sure that npcs actually use items, we'll make Item from it )
			{
				writeD(itemId);
				writeD(0x00);
				writeD(0x00);
				writeH(0x00);
			}
		}

		if (template.getBoundRadius() == null)
		{
			writeF(1.0f);// unk
			writeF(0);
		}
		else
		{
			writeF(template.getBoundRadius().getCollision()*template.getBoundRadius().getCollision());
			writeF(template.getBoundRadius().getUpper());
		}
		writeF(npc.getGameStats().getMovementSpeed().getCurrent()/1000f);// speed
		Stat attackSpeed = npc.getGameStats().getAttackSpeed();
		writeH(attackSpeed.getBaseInt());
		writeH(attackSpeed.getCurrentInt());

		writeC(0x00);// unk

		/**
		 * Movement
		 */
		if (npc instanceof Creature)
		{
			MoveData m = ((Creature)npc).getMoveData();
			writeF(m.xTarget);// x
			writeF(m.yTarget);// y
			writeF(m.zTarget);// z
			writeC(m.movementMask); // move type
		}
		else
		{
			writeF(npc.getX());// x
			writeF(npc.getY());// y
			writeF(npc.getZ());// z
			writeC(0x00); // move type
		}
		SpawnTemplate spawn = npc.getSpawn();
		if (spawn == null)
			writeH(0);
		else
			writeH(spawn.getStaticid());
		writeC(0);
		writeC(0); // all unknown
		writeC(0);
		writeC(0);
		writeC(0);
		writeC(0);
		writeC(0);
		writeC(0);
		writeC(npc.getVisualState()); // visualState

		/**
		 * 1 : normal (kisk too)
		 * 2 : summon
		 * 32 : trap
		 * 1024 : holy servant, noble energy
		 */
		//TODO ??????????
		writeH(npc.getNpcTypeId());
		writeC(0x00);// unk
		writeD(npc.getTarget() == null ? 0 : npc.getTarget().getObjectId());
	}
}
